$.fn.autoComplete = function (options) {
    // 默认选项
    var opt = {
        // 是否单选
        single: false,

        // 最大标签数
        max: 5,
        
        // Ajax 请求地址
        url: '',
        urlPostfix: '.html',
        enableUrlPostfix: true,

        // 输入框属性
        name: '',
        id: '',
        placeholder: '',

        waiter: 500,

        inputClass: '',
        inputCss: {},

        listClass: '',
        listCss: {},

        listItemClass: '',
        listItemCss: {},

        listItemReadyClass: '',
        listItemReadyCss: {},

        listItemHintClass: '',
        listItemHintCss: {},

        labelClass: '',
        labelCss: {},

        labelItemClass: '',
        labelItemCss: {},

        labelContainerId: '',

        enableSpace: false,
        enableEnter: true,
        enableEsc: true,
        enableArrow: true,
        enableAutoDefine: false,

        defineFunc: undefined,
        clickLabelFunc: undefined
    };

    $.extend(true, opt, options);

    // 初始化对象
    var complete = new AutoComplete(this);

    // ajax timer
    var timer;

    // 上次输入时选中的提示索引
    var selectedIndex = 0;

    // 可选索引
    var selectList = [];
    var selectItems = [];

    // 已选列表
    var selectedElements;
    if (complete.preset) {
        selectedElements = (opt.single) ? complete.preset : eval(complete.preset);
        renderLabel();
    } else {
        selectedElements = (opt.single) ? '' : [];
    }

    // 点击 container 使 Input 获得焦点
    complete.container.on('click', function () {
        complete.input.focus();
    });

    // 输入框获得焦点
    complete.input.on('focus input', function () {
        showBox();
    });

    // 点击区域非输入框或下拉框
    complete.input.on('click', function () {
        return false;
    });

    complete.list.on('click', function () {
        return false;
    });

    $(document).on('click', function () {
        hideBox();
    });

    // 自动提示
    complete.input.on('keyup', function (e) {
        // 元素限制
        if (!opt.single && selectedElements.length >= opt.max) {
            return;
        }

        if (opt.enableSpace && e.keyCode == 32) { // 空格
            var temp = complete.list.find('li.selElementOne.ready');
            if (temp.length == 1) {
                addElementLabel(temp.attr('data-element'));
            } else if (opt.enableAutoDefine) {
                addElementLabel($(this).val().trim());
            } else if ((typeof opt.defineFunc).toLowerCase() == 'function') {
                opt.defineFunc($(this).val().trim());
            }
        } else if (opt.enableEnter && e.keyCode == 13) { // 回车
            var temp = complete.list.find('li.selElementOne.ready');
            if (temp.length == 1) {
                addElementLabel(temp.attr('data-element'));
            } else if (opt.enableAutoDefine) {
                addElementLabel($(this).val().trim());
            } else if ((typeof opt.defineFunc).toLowerCase() == 'function') {
                opt.defineFunc($(this).val().trim());
            }
        } else if (opt.enableEsc && e.keyCode == 27) { // ESC
            hideBox();
        } else {
            if (e.keyCode == 38 || e.keyCode == 40) { // Up and Down
                return;
            }
            clearTimeout(timer);
            timer = setTimeout(function () {
                var text = complete.input.val();

                if (text.length == 0) {
                    complete.list.html('');
                    return;
                }
        
                $.ajax({
                    url: opt.url + '/' + text + '.html',
                    type: 'GET',
                    dataType: 'json',
                    crossDomain: true,
                    success: function (data) {
                        complete.list.html('');
        
                        selectList = [];
                        selectItems = [];
        
                        $.each(data, function (index, item) {
                            selectList.push(index);
                            selectItems.push(item);
                            var tempLi = $('<li>').attr('data-element', item)
                                .addClass('selElementOne')
                                .addClass(opt.listItemClass)
                                .css(opt.listItemCss);
                            if (selectedIndex == index) {
                                tempLi.addClass('ready ' + opt.listItemReadyClass)
                                    .css(opt.listItemReadyCss);
                            }
                            var tempSp = $('<span>').addClass('selElementHint')
                                .addClass(opt.listItemHintClass)
                                .css(opt.listItemHintCss);
                            tempLi.append(tempSp.html(text)).append(item.substr(text.length));
                            complete.list.append(tempLi);
                        });
                    },
                    error: function (data) {
                        console.log('error:');
                        console.log(data);
                    }
                });
            }, opt.waiter);
        }
    });

    // keydown
    complete.input.on('keydown', function (e) {
        // 回车删除已选标签
        if (!opt.single && selectedElements.length > 0 && $(this).val().length === 0 && e.keyCode === 8)
        {
            hideBox();
            selectedElements.pop();
            renderLabel();
            return;
        }

        if (selectList.length == 0 || !opt.enableArrow) {
            return;
        }

        if (e.keyCode == 38) {
            // 上键
            selectedIndex--;
            while (selectList.indexOf(selectedIndex) == -1 && selectedIndex >= 0) {
                selectedIndex--;
            }
            selectedIndex = (selectedIndex < 0) ? selectList[selectList.length - 1] : selectedIndex;
            e.preventDefault();
            renderList($(this).val());
        } else if (e.keyCode == 40) {
            // 下键
            selectedIndex++;
            while (selectList.indexOf(selectedIndex) == -1 && selectedIndex < selectList.length) {
                selectedIndex++;
            }
            selectedIndex = (selectedIndex >= selectList.length) ? selectList[0] : selectedIndex;
            e.preventDefault();
            renderList($(this).val());
        }
    });

    // 下拉待选项 - 鼠标覆盖
    complete.list.on('mouseover', 'li.selElementOne', function () {
        complete.list.find('li.selElementOne')
            .removeClass('ready')
            .removeClass(opt.listItemReadyClass)
            .removeAttr('style');
        $(this).addClass('ready ' + opt.listItemReadyClass)
            .css(opt.listItemReadyCss);
        // 寻找序号
        var temp = $(this).attr('data-element');
        if (temp != undefined) {
            selectedIndex = selectItems.indexOf(temp);
        }
    });

    // 点击列表项
    complete.list.on('click', 'li.selElementOne.ready', function () {
        addElementLabel($(this).attr('data-element'));
    });

    // 点击标签删除按钮
    complete.labels.on('click', 'span.selectedItem > .remove', function () {
        var text = $(this).parent().first().text()
        text = text.substr(0, text.length - 1);
        if ((typeof opt.clickLabelFunc).toLowerCase() == 'function') {
            opt.clickLabelFunc(text);
        } else {
            delElementLabel(text);
        }
    });

    // TODO 添加新标签
    function addElementLabel(str, inx) {
        hideBox();
        
        if (opt.single) { // 单选时
            selectedElements = str;
        } else {
            if (inx >= 0 && inx < selectedElements.length) {
                selectedElements.splice(inx, 0, str);
            } else {
                selectedElements.push(str);
            }
        }
        renderLabel();
    }

    // 删除标签
    function delElementLabel(str, inx) {
        if (opt.single) {
            selectedElements = '';
        } else {
            if (inx == undefined) {
                inx = selectedElements.indexOf(str);
            }
            if (inx >= 0 && inx < selectedElements.length) {
                selectedElements.splice(inx, 1);
            }
        }
        renderLabel();
    }

    // 渲染已选标签
    function renderLabel() {
        if (opt.single) {
            complete.input.val(selectedElements);
        } else {
            complete.labels.html('');
            for (var i = 0, len = selectedElements.length; i < len; i++) {
                var temp = $('<span>')
                    .addClass('selectedItem')
                    .addClass(opt.labelItemClass)
                    .css(opt.labelItemCss)
                    .html(selectedElements[i]);
                var remv = $('<span>').addClass('remove').text('×');
                temp.append(remv);
                complete.labels.append(temp).append('\n');
            }
        }
    }

    // 渲染选择表
    function renderList(text) {
        complete.list.html('');

        if (text.length == 0) {
            return;
        }

        $.each(selectList, function (index, item) {
            var position = selectList[index];
            var data = selectItems[position];
            var tempLi = $('<li>').attr('data-element', data)
                .addClass('selElementOne')
                .addClass(opt.listItemClass)
                .css(opt.listItemCss);
            if (selectedIndex == index) {
                tempLi.addClass('ready ' + opt.listItemReadyClass)
                    .css(opt.listItemReadyCss);
            }
            var tempSp = $('<span>').addClass('selElementHint')
                .addClass(opt.listItemHintClass)
                .css(opt.listItemHintCss);
            tempLi.append(tempSp.html(text)).append(data.substr(text.length));
            complete.list.append(tempLi);
        });
    };

    // 下拉框弹出
    function showBox() {
        complete.list.css({
            'display': 'block',
            'left': complete.input.position().left + 'px'
        });
    };

    // 下拉框隐藏
    function hideBox() {
        complete.list.css('display', 'none').html('');
        if (!opt.single) {
            complete.input.val('');
        }
        selectedIndex = 0;
    };

    // 初始化控件对象
    function AutoComplete(element) {
        this.preset = element.text();

        this.container = element.addClass('MuseAutocompleteContainer field');

        // 已选标签
        if (opt.labelContainerId != '' && $('#' + opt.labelContainerId).length == 1) {
            this.labels = $('#' + opt.labelContainerId);
        } else {
            this.labels = $('<span>').addClass('selectedElementsLabel ' + opt.labelClass)
                .css(opt.labelCss);
        }

        // 输入框
        this.input = $('<input>').attr({
            type: 'text',
            placeholder: opt.placeholder,
            name: opt.name,
            id: opt.id
        })
            .addClass('selectElementInput ' + opt.inputClass)
            .css(opt.inputCss);

        // 下拉选择表
        this.list = $('<ul>').addClass('selectElementsBox ' + opt.listClass)
            .css(opt.listCss);

        // 初始化DOM结构
        this.container.html('');
        if (opt.labelContainerId == '' || $('#' + opt.labelContainerId).length != 1) {
            this.container.append(this.labels);
        }
        this.container.append(this.input).append(this.list);
    }

    AutoComplete.prototype.getSelecteds = function () { // 获得已选所有标签
        return selectedElements;
    };

    AutoComplete.prototype.setElement = function (str) {
        if (opt.single) {
            addElementLabel(str);
        }
    };

    AutoComplete.prototype.clearElement = function () {
        if (opt.single) {
            delElementLabel();
        }
    };

    AutoComplete.prototype.addSelected = function (str, inx) {
        addElementLabel(str.toString(), parseInt(inx));
    };

    AutoComplete.prototype.delSelected = function (str, isNum) {
        if (opt.single) {
            delElementLabel();
        } else {
            if (isNum) {
                delElementLabel('', parseInt(str));
            } else {
                delElementLabel(str.toString());
            }
        }
    };

    AutoComplete.prototype.spliceElement = function (inx, num) {
        if (opt.single) {
            return;
        }
        for (var i = 0; i < num; i++) {
            delElementLabel('', parseInt(inx));
        }
        if (arguments.length > 2) {
            for (var i = arguments.length - 1; i >= 2; i--) {
                addElementLabel(arguments[i].toString(), parseInt(inx));
            }
        }
    };

    AutoComplete.prototype.editElement = function (str1, str2, isNum) {
        if (opt.single) {
            return;
        }
        if (!isNum) {
            str1 = selectedElements.indexOf(str1);
        }
        str1 = parseInt(str1);
        if (str1 >= 0 && str1 < selectedElements.length) {
            this.spliceElement(str1, 1, str2);
        }
    };

    return complete;
};